home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr44 / ppl4c10.zip / AMODEM.C < prev    next >
Text File  |  1995-02-11  |  10KB  |  296 lines

  1. /*
  2. **  ASCII text file transfer using XON / OFF flow control protocol.
  3. **  Transfer ASCII files only. Do not attempt to transfer binary files.
  4. */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <fcntl.h>
  9. #include <string.h>
  10. #include <io.h>
  11. #include <sys\types.h>
  12. #include <sys\stat.h>
  13.  
  14. #include "pcl4c.h"
  15. #include "ascii.h"
  16. #include "term_io.h"
  17. #include "xymodem.h"
  18. #include "amodem.h"
  19. #include "term.h"
  20. #include "win_io.h"
  21.  
  22. #define FALSE 0
  23. #define TRUE !FALSE
  24.  
  25. #define ONE_SECOND 18
  26.  
  27. char lastXchar;     /* last XON or XOFF sent */
  28.  
  29. int TxAscii(
  30.   int Port,            /* COM port [0..3] */
  31.   char Filename[],     /* filename buffer */
  32.   char Buffer[],       /* data buffer */
  33.   int Length,          /* size of Buffer */
  34.   int SyncFlag,        /* synchronize with XON 1st */
  35.   int CharPace,        /* millisecond delay after sending each character */
  36.   int TermChar,        /* termination character (0x00 ==> none) */
  37.   int EchoFlag)        /* do local echo if TRUE */
  38. {int i;
  39.  int Code;           /* return code */
  40.  int Handle;         /* file Handle */
  41.  char LastChar;      /* last character sent */
  42.  int TxChars = 0;    /* # characters transmitted */
  43.  int Count;          /* # bytes read from disk */
  44.  char Temp[81];      /* temporary buffer */
  45.  /* begin */
  46.  if(!FetchName(Filename)) return FALSE;
  47.  Handle = open(Filename,O_RDONLY|O_BINARY,S_IREAD);
  48.  if(Handle<0)
  49.      {strcpy(Temp,"Cannot open ");
  50.       strcat(Temp,Filename);
  51.       WriteMsg(Temp);
  52.       return FALSE;
  53.      }
  54.  /* do we wait for XON before starting ? */
  55.  if(SyncFlag)
  56.    {/* wait for incoming XON */
  57.     WriteMsg("ASCII: Waiting for XON");
  58.     while(1)
  59.        {if(SioBrkKey())
  60.           {WriteMsg("Canceled by USER");
  61.            return FALSE;
  62.           }
  63.         Code = CharGet(Port,ONE_SECOND);
  64.         if(Code==-1) continue;
  65.         if(Code<0) return FALSE;
  66.         if((char)Code==XON)
  67.            {WriteMsg("ASCII: initial XON received");
  68.             /* slight delay */
  69.             SioDelay(ONE_SECOND/2);
  70.             break;
  71.            }
  72.         /* received character not XON */
  73.         WinPutChar(SCR_WIN,(char)Code);
  74.        }
  75.    }
  76.  /* begin transfer */
  77.  lastXchar =  XON;
  78.  WriteMsg("ASCII: Starting send");
  79.  while(SioKeyPress()) SioKeyRead();
  80.  /* clear comm port */
  81.  SioRxFlush(Port);
  82.  /* send ascii file ( stop at ^Z ) */
  83.  while(1)
  84.      {/* read next buffer from disk */
  85.       Count = read(Handle,Buffer,Length);
  86.       if(Count==0) break;
  87.       if(Count<0)
  88.           {SayError(Port,"Error on disk read");
  89.            return FALSE;
  90.           }
  91.       /* send one byte at a time */
  92.       for(i=0;i<Count;i++)
  93.           {/* User ABORTS ? */
  94.            if(UserAborts(Port)) return FALSE;
  95.            /* send byte */
  96.            LastChar = Buffer[i];
  97.            if(EchoFlag) WinPutChar(SCR_WIN,LastChar);
  98.            /* send the character */
  99.            CharPut(Port,LastChar);
  100.            if(CharPace>0) SioDelay(CharPace);
  101.            /* slight delay after each line */
  102.            if(LastChar==LF) SioDelay(4*(CharPace+1));
  103.            TxChars++;
  104.            /* ^Z marks the end of a text file */
  105.            if(LastChar==CTLZ) break;
  106.            /* check for incoming XON */
  107.            if(lastXchar==XON)
  108.                 {/* check for incoming XON / XOFF */
  109.                  Code = CharGet(Port,0);
  110.                  if(Code>0)
  111.                     {/* is byte a XOFF ? */
  112.                      if((char)Code==XOFF)
  113.                          {/* wait for XON */
  114.                           WriteMsg("XOFF received");
  115.                           lastXchar = XOFF;
  116.                           /* wait for XON */
  117.                           while(1)
  118.                               {/* user want to quit ? */
  119.                                if(SioBrkKey())
  120.                                    {WriteMsg("Canceled by USER");
  121.                                     return FALSE;
  122.                                    }
  123.                                Code = CharGet(Port,ONE_SECOND);
  124.                                if((char)Code==XON)
  125.                                    {WriteMsg("XON  received");
  126.                                     lastXchar = XON;
  127.                                     break;
  128.                                    }
  129.                               } /* end -- while */
  130.                          } /* end -- if(XOFF) */
  131.                     } /* end -- if(Code) */
  132.                 } /* end -- if(XON) */
  133.  
  134.           } /* end -- for(i) */
  135.      } /* end -- while */
  136.  close(Handle);
  137.  /* send termination character */
  138.  if(TermChar) CharPut(Port,(char)TermChar);
  139.  sprintf(Temp,"ASCII: %d chars sent.",TxChars);
  140.  WriteMsg(Temp);
  141.  return TRUE;
  142. } /* end -- TxAcsii */
  143.  
  144. int RxAscii(
  145.   int Port,            /* COM port [0..3] */
  146.   char Filename[],     /* filename buffer */
  147.   char Buffer[],       /* data buffer */
  148.   int Length,          /* length of data buffer */
  149.   int RxQueSize,       /* size of PCL receive buffer */
  150.   int SyncFlag,        /* synchronize with XON 1st */
  151.   int TermChar,        /* termination character (0x00 ==> none) */
  152.   int TimeOut,         /* delay (seconds) before assuming that sender is done */
  153.   int EchoFlag)        /* do local echo if TRUE */
  154. {int i;
  155.  int Handle;         /* file Handle */
  156.  int Code;           /* return code */
  157.  int lo;             /* receive queue low water mark */
  158.  int hi;             /* receive queue high water mark */
  159.  int Index;          /* buffer index */
  160.  int QueSize;        /* current PCL receive queue size */
  161.  int RxChars = 0;    /* # received chars */
  162.  int Count;          /* # characters written to disk */
  163.  char Temp[81];      /* temporary buffer */
  164.  long LastTime;      /* time last character was received */
  165.  /* begin */
  166.  lastXchar = XON;
  167.  lo = RxQueSize / 8;
  168.  hi = 5 * lo;
  169.  WriteMsg("ASCII: Starting receive ");
  170.  while(SioKeyPress()) SioKeyRead();
  171.  /* clear comm port */
  172.    /*SioRxFlush(Port);*/
  173.  /* open file passed in Filename[] for write */
  174.  if(!FetchName(Filename)) return FALSE;
  175.  Handle = open(Filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IWRITE);
  176.  if(Handle<0)
  177.      {strcpy(Temp,"Cannot open ");
  178.       strcat(Temp,Filename);
  179.       WriteMsg(Temp);
  180.       return FALSE;
  181.      }
  182.  /* sync with XON 1st ? */
  183.  if(SyncFlag)
  184.     {WriteMsg("ASCII: Sending initial XON");
  185.      while(1)
  186.         {CharPut(Port,XON);
  187.          Code = CharGet(Port,ONE_SECOND);
  188.          if(Code==-1) continue;
  189.          /* transmitter is sending ! */
  190.          SioUnGetc(Port,(char)Code);
  191.          break;
  192.         }
  193.     }
  194.  /* receive text */
  195.  LastTime = SioTimer();
  196.  Index = 0;
  197.  while(1)
  198.      {/* user want to quit ? */
  199.       if(SioBrkKey())
  200.           {WriteMsg("Canceled by USER");
  201.            return FALSE;
  202.           }
  203.       /* check on PCL receive queue size */
  204.       QueSize = SioRxQue(Port);
  205.       if((QueSize>hi)&&(lastXchar==XON))
  206.           {CharPut(Port,XOFF);
  207.            lastXchar = XOFF;
  208.            WriteMsg("sending XOFF(1)");
  209.            /*sprintf(Temp,"\nQueSize=%d lo=%d hi=%d\n",QueSize,lo,hi);*/
  210.            /*WriteMsg(Temp);*/
  211.           }
  212.       if((QueSize<lo)&&(lastXchar==XOFF))
  213.           {CharPut(Port,XON);
  214.            lastXchar = XON;
  215.            WriteMsg("sending XON ");
  216.           }
  217.       /* User ABORTS ? */
  218.       if(UserAborts(Port)) return FALSE;
  219.       /* get next byte */
  220.       Code = CharGet(Port,ONE_SECOND);
  221.       if(Code==-1)
  222.          {/* done if have exceeded timeout */
  223.           if(SioTimer()-LastTime>ONE_SECOND*TimeOut)
  224.             {/* sender must be done */
  225.              Buffer[Index] = CTLZ;
  226.              break;
  227.             }
  228.           continue;
  229.          }
  230.       /* ignore 1st character if it is a 0 */
  231.       if((RxChars==0)&&((char)Code=='\0')) continue;
  232.       LastTime = SioTimer();
  233.       /* ignore XON & XOFF ( since we are the receiver ) */
  234.       if((char)Code==XON) continue;
  235.       if((char)Code==XOFF) continue;
  236.       /* received a character */
  237.       Buffer[Index++] = (char)Code;
  238.       RxChars++;
  239.       /* TermChar marks the end of a text file */
  240.       if((char)Code==TermChar)
  241.           {/* replace TermChar with ^Z */
  242.            Buffer[Index-1] = CTLZ;
  243.            RxChars++;
  244.            break;
  245.           }
  246.       if(EchoFlag) WinPutChar(SCR_WIN,(char)Code);
  247.       if(Index==Length)
  248.           {/* send XOFF to transmitter */
  249.            CharPut(Port,XOFF);
  250.            lastXchar = XOFF;
  251.            WriteMsg("sending XOFF(2)");
  252.            /* write disk file */
  253.            Count = write(Handle,Buffer,Index);
  254.            if(Count<0)
  255.                {SayError(Port,"Disk write error");
  256.                 SioDelay(ONE_SECOND);
  257.                 return FALSE;
  258.                }
  259.            /* send XON to sender */
  260.            CharPut(Port,XON);
  261.            lastXchar = XON;
  262.            WriteMsg("sending XON ");
  263.            Index = 0;
  264.           } /* end -- if */
  265.      } /* end -- while */
  266.  /* write any remaining data in buffer */
  267.  if(Index>0)
  268.      {Count = write(Handle,Buffer,Index);
  269.       if(Count<0)
  270.           {SayError(Port,"Disk write error");
  271.            SioDelay(ONE_SECOND);
  272.            return FALSE;
  273.           }
  274.      } /* end -- if */
  275.  close(Handle);
  276.  sprintf(Temp,"ASCII: %d chars received.",RxChars);
  277.  WriteMsg(Temp);
  278.  return TRUE;
  279. } /* RxAscii */
  280.  
  281. int UserAborts(int Port)
  282. {char UserChar;
  283.  /* user aborts ? */
  284.  if(SioKeyPress())
  285.     {UserChar = (char)SioKeyRead();
  286.      if(UserChar==CAN)
  287.        {TxCAN(Port);
  288.         CharPut(Port,ETX);
  289.         WriteMsg("*** Canceled by USER ***");
  290.         return TRUE;
  291.        }
  292.      /* send user char */
  293.      CharPut(Port,UserChar);
  294.     }
  295.  return FALSE;
  296. } /* UserAborts */